package com.icee.myth.server.channelHandler;

import com.icee.myth.common.messageQueue.ServerMessageQueue;
import com.icee.myth.common.protobufMessage.ProtobufMessageType;
import com.icee.myth.log.GameLogger;
import com.icee.myth.log.message.builder.GameLogMessageBuilder;
import com.icee.myth.protobuf.ExternalCommonProtocol.IntValueProto;
import com.icee.myth.protobuf.InternalCommonProtocol.M2SGmProto;
import com.icee.myth.server.message.serverMessage.builder.MapMessageBuilder;
import com.icee.myth.utils.LogConsts;
import com.icee.myth.utils.MLogger;
import com.icee.myth.utils.StackTraceUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.io.IOException;

/**
 * 服务器与服务器通信，manager服务器（客户端）连游戏服务器，游戏服务器端处理的Handler
 * @author liuxianke
 */
public class ManagerConnectHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // Add GW channel connected message to message queue
        ServerMessageQueue.queue().offer(MapMessageBuilder.buildManagerConnectMessage(ctx.channel()));
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        // Add GW channel close message to message queue
        ServerMessageQueue.queue().offer(MapMessageBuilder.buildManagerCloseMessage(ctx.channel()));
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            // Add GW channel received message to message queue
            ByteBuf cb = (ByteBuf) msg;
            short type = cb.readShort();
            short length = cb.readShort();

            switch (type) {
                case ProtobufMessageType.MANAGER2SERVER_HEARTBEAT: {
                    ServerMessageQueue.queue().offer(MapMessageBuilder.buildManagerHeartbeatMessage());
                    break;
                }
                case ProtobufMessageType.MANAGER2SERVER_SHUTDOWN: {
                    ServerMessageQueue.queue().offer(MapMessageBuilder.buildShutdownMessage());
                    break;
                }
                case ProtobufMessageType.MANAGER2SERVER_GM: {
                    M2SGmProto gmProto = M2SGmProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(cb)).build();
                    ServerMessageQueue.queue().offer(MapMessageBuilder.buildGmMessage(gmProto));
                    break;
                }
                case ProtobufMessageType.MANAGER2SERVER_BILLNOTIFY: {
                    IntValueProto intValue = IntValueProto.getDefaultInstance().newBuilderForType().mergeFrom(new ByteBufInputStream(cb)).build();
                    ServerMessageQueue.queue().offer(MapMessageBuilder.buildBillNotifyMessage(intValue.getValue()));
                    break;
                }
                case ProtobufMessageType.MANAGER2CLUSTER_GETSERVERVERSION:{

                }
                // TODO: other message
            }
        } catch (IOException ex) {
            GameLogger.getlogger().log(GameLogMessageBuilder.buildFileNetErrorGameLogMessage(StackTraceUtil.getStackTrace(ex)));
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Exception {
        MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_DEBUG, "ManagerConnectHandler: " + StackTraceUtil.getStackTrace(e));
        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileNetErrorGameLogMessage(StackTraceUtil.getStackTrace(e.getCause())));
        // TODO:发生异常是否需要关闭与GW的连接
//        ctx.channel().close();
    }

}
